﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jinjia.Approve.Common.Enum;
using Jinjia.Approve.Entity.Entity.JJFlow;
using Jinjia.Approve.IRepository.JJFlow;
using Jinjia.Approve.Model.VM.JJFlow;
using Jinjia.Core.UnitOfWork.UnitOfWorkComponent;
using SqlSugar;

namespace Jinjia.Approve.Repository.JJFlow
{
    public class FlowNodeRepository : IFlowNodeRepository
    {
        private readonly ISqlSugarClient _db;

        public FlowNodeRepository(IUnitOfWork unitOfWork)
        {
            _db = unitOfWork.GetDbClient();
        }

        public async Task<List<jj_node>> GetNodes(int template_id)
        {
            return await _db.Queryable<jj_node>().Where(x => x.template_id == template_id && x.deleted == 0).ToListAsync();
        }

        public async Task<List<jj_node>> GetNodes(int template_id, int node_type)
        {
            return await _db.Queryable<jj_node>().Where(x => x.template_id == template_id && x.node_type == 2 && x.deleted == 0).ToListAsync();
        }

        public async Task<jj_node> GetStartNode(int template_id)
        {
            var jjNodes = await GetNodes(template_id);
            return jjNodes.First(p => p.node_type == (int)EnumDb.JJFlowNodeTypeEnum.StartNode);
        }

        public async Task<int> Save(jj_node data)
        {
            if (data.id <= 0) //新增
            {
                var id = await _db.Insertable(data).ExecuteReturnIdentityAsync();
                return id;
            }
            else
            {
                await _db.Updateable(data)
                    .Where(x => x.id == data.id)
                    .ExecuteCommandAsync();
                return data.id;
            }
        }

        public async Task<List<jj_node>> GetNodesPlan(int flow_instance_id)
        {
            var jjNodes = await _db.Queryable<jj_node_reference, jj_node>((a, b) => new JoinQueryInfos(JoinType.Left, a.node_id == b.id))
                .Where(a => a.flow_instance_id == flow_instance_id)
                .Select<jj_node>("b.*")
                .ToListAsync();
            return jjNodes;
        }

        public async Task<jj_node> GetById(int nodeId)
        {
            var jjNode = await _db.Queryable<jj_node>().Where(x => x.id == nodeId).FirstAsync();
            return jjNode;
        }

        public async Task<List<jj_node>> GetByIds(List<int> nodeIds)
        {
            return await _db.Queryable<jj_node>().In(x => x.id, nodeIds).ToListAsync();
        }

        public async Task<List<Node>> GetNodeByInstanceIds(List<int> instanceIds)
        {
            return await _db.Queryable<jj_node_reference, jj_node>((a, b) => new JoinQueryInfos(JoinType.Left, a.node_id == b.id))
                .In(a => a.flow_instance_id, instanceIds)
                .Select<Node>(" b.*,a.flow_instance_id ").ToListAsync();
        }

        public async Task<bool> CheckNodeIsComplete(int instance_id, int template_id, int node_id)
        {
            var list = await _db.Queryable<jj_flow_instance_emp>()
                .Where(a => a.instance_id == instance_id && a.template_id == template_id && a.node_id == node_id && a.is_complete == 0)
                .ToListAsync();
            return list.Count <= 0;
        }
    }
}